# ~*~ coding: utf-8 ~*~
from flask import request, views, render_template, jsonify
from flask_login import current_user

from apps.common.utils import fill_date_to_timestamp, timestamp_obj_to_str, list2dict
from apps.common.mixin import CompatibleWithSelect2Mixin
from apps.common import response
from apps.extensions import db
from apps.perms.mixin import PermissionRequiredMixin, LoginRequiredMixin
from ...models import Function
from ...forms import FunctionForm


__all__ = [
    'FunctionListAPI', 'FunctionListView',
    'FunctionCreateView', 'FunctionUpdateView',
    'FunctionDeleteView', 'FunctionItemAPI'
]


class FunctionListAPI(CompatibleWithSelect2Mixin, PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'tasks-function-list'

    def get(self):
        create_time = request.args.get('create_time')
        start_time = end_time = None
        if create_time:
            start_time = fill_date_to_timestamp('start', create_time.split('~')[0])
            end_time = fill_date_to_timestamp('end', create_time.split('~')[1])

        filter_conditions = {
            'and': [
                ('create_time', 'gte', start_time),
                ('create_time', 'lte', end_time),
            ],
            'or': [
                ('name', 'like', request.args.get('search')),
            ],
        }

        # 排序
        sort = request.args.get('sort') or 'create_time'
        order = request.args.get('order') or 'desc'
        order_by_list = [(sort, order), ]

        # 分页
        offset = request.args.get('offset') or 0
        limit = request.args.get('limit') or 12

        # Compatible with select2
        if request.values.get('type') == 'select2':
            filter_conditions, order_by_list, offset, limit = self.select2_queryset()

        functions, count = Function.get_queryset(filter_conditions=filter_conditions,
                                                 order_by_list=order_by_list,
                                                 offset=offset, limit=limit)

        results = list()
        for function in functions:
            results.append({
                'id': function.id,
                'name': function.name,
                'method': function.method,
                'description': function.description,
                'create_by': function.create_by,
                'create_time': timestamp_obj_to_str(function.create_time)
            })

        resp = {
            "data": {
                "rows": results,
                "total": count
            }
        }
        return jsonify(resp)


class FunctionItemAPI(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):

    def has_perm(self):
        return True

    def get(self, pk):
        instance = db.session.query(Function).get(pk)
        content = {
            'id': instance.id,
            'name': instance.name,
            'method': instance.method,
            'description': instance.description,
            'create_by': instance.create_by,
            'create_time': timestamp_obj_to_str(instance.create_time)
        }
        resp = {
            "data": content
        }
        return jsonify(resp)


class FunctionListView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'tasks-function-list'

    def get(self):
        return render_template('tasks/periodic/function_list.html')


class FunctionUpdateView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'tasks-function-update'

    def get(self, pk):
        instance = db.session.query(Function).get(pk)
        content = {
            'id': instance.id,
            'name': instance.name,
            'method': instance.method,
            'description': instance.description,
        }
        return render_template('tasks/periodic/function_update.html', **content)

    def post(self, pk):
        form = FunctionForm(request.values)
        instance = db.session.query(Function).get(pk)
        if form.validate():
            _clean_data = form.data
            if instance.name != _clean_data.get('name'):
                if db.session.query(Function).filter_by(name=_clean_data.get('name')).count():
                    return response.params_error({
                        'field': 'name',
                        'message': '函数名称不能重复'
                    })

            instance.update(**_clean_data)
            return response.success()
        else:
            return response.params_error(form.get_error())


class FunctionCreateView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'tasks-function-create'

    def get(self):
        return render_template('tasks/periodic/function_create.html')

    def post(self):
        form = FunctionForm(request.values)
        if form.validate():
            _clean_data = form.data
            if db.session.query(Function).filter_by(name=_clean_data.get('name')).count():
                return response.params_error({
                    'field': 'name',
                    'message': '函数名称不能重复'
                })

            _clean_data['create_by'] = current_user.name
            Function.create(**_clean_data)
            return response.success()
        else:
            return response.params_error(form.get_error())


class FunctionDeleteView(PermissionRequiredMixin, LoginRequiredMixin, views.MethodView):
    permission_required = 'tasks-function-delete'

    def post(self, pk):
        instance = db.session.query(Function).get(pk)
        instance.delete()
        return response.success()

